home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) ''' Complete implementation of the XDG Icon Spec Version 0.8 http://standards.freedesktop.org/icon-theme-spec/ ''' import os import sys import time from xdg.IniFile import * from xdg.BaseDirectory import * from xdg.Exceptions import * import xdg.Config as xdg class IconTheme(IniFile): '''Class to parse and validate IconThemes''' def __init__(self): IniFile.__init__(self) def __repr__(self): return self.name def parse(self, file): IniFile.parse(self, file, [ 'Icon Theme', 'KDE Icon Theme']) self.dir = os.path.dirname(file) (nil, self.name) = os.path.split(self.dir) def getDir(self): return self.dir def getName(self): return self.get('Name', locale = True) def getComment(self): return self.get('Comment', locale = True) def getInherits(self): return self.get('Inherits', list = True) def getDirectories(self): return self.get('Directories', list = True) def getHidden(self): return self.get('Hidden', type = 'boolean') def getExample(self): return self.get('Example') def getSize(self, directory): return self.get('Size', type = 'integer', group = directory) def getContext(self, directory): return self.get('Context', group = directory) def getType(self, directory): value = self.get('Type', group = directory) if value: return value return 'Threshold' def getMaxSize(self, directory): value = self.get('MaxSize', type = 'integer', group = directory) if value or value == 0: return value return self.getSize(directory) def getMinSize(self, directory): value = self.get('MinSize', type = 'integer', group = directory) if value or value == 0: return value return self.getSize(directory) def getThreshold(self, directory): value = self.get('Threshold', type = 'integer', group = directory) if value or value == 0: return value return 2 def checkExtras(self): if self.defaultGroup == 'KDE Icon Theme': self.warnings.append('[KDE Icon Theme]-Header is deprecated') if self.fileExtension == '.theme': pass elif self.fileExtension == '.desktop': self.warnings.append('.desktop fileExtension is deprecated') else: self.warnings.append('Unknown File extension') try: self.name = self.content[self.defaultGroup]['Name'] except KeyError: self.errors.append("Key 'Name' is missing") try: self.comment = self.content[self.defaultGroup]['Comment'] except KeyError: self.errors.append("Key 'Comment' is missing") try: self.directories = self.content[self.defaultGroup]['Directories'] except KeyError: self.errors.append("Key 'Directories' is missing") def checkGroup(self, group): if group == self.defaultGroup: pass elif group in self.getDirectories(): try: self.type = self.content[group]['Type'] except KeyError: self.type = 'Threshold' try: self.name = self.content[group]['Name'] except KeyError: self.errors.append("Key 'Name' in Group '%s' is missing" % group) except: None<EXCEPTION MATCH>KeyError None<EXCEPTION MATCH>KeyError if not re.match('^\\[X-', group) and group.decode('utf-8', 'ignore').encode('ascii', 'ignore') == group: self.errors.append('Invalid Group name: %s' % group) def checkKey(self, key, value, group): if group == self.defaultGroup: if re.match('^Name' + xdg.Locale.regex + '$', key): pass elif re.match('^Comment' + xdg.Locale.regex + '$', key): pass elif key == 'Inherits': self.checkValue(key, value, list = True) elif key == 'Directories': self.checkValue(key, value, list = True) elif key == 'Hidden': self.checkValue(key, value, type = 'boolean') elif key == 'Example': self.checkValue(key, value) elif re.match('^X-[a-zA-Z0-9-]+', key): pass else: self.errors.append('Invalid key: %s' % key) elif group in self.getDirectories(): if key == 'Size': self.checkValue(key, value, type = 'integer') elif key == 'Context': self.checkValue(key, value) elif key == 'Type': self.checkValue(key, value) if value not in ('Fixed', 'Scalable', 'Threshold'): self.errors.append("Key 'Type' must be one out of 'Fixed','Scalable','Threshold', but is %s" % value) elif key == 'MaxSize': self.checkValue(key, value, type = 'integer') if self.type != 'Scalable': self.errors.append("Key 'MaxSize' give, but Type is %s" % self.type) elif key == 'MinSize': self.checkValue(key, value, type = 'integer') if self.type != 'Scalable': self.errors.append("Key 'MinSize' give, but Type is %s" % self.type) elif key == 'Threshold': self.checkValue(key, value, type = 'integer') if self.type != 'Threshold': self.errors.append("Key 'Threshold' give, but Type is %s" % self.type) elif re.match('^X-[a-zA-Z0-9-]+', key): pass else: self.errors.append('Invalid key: %s' % key) class IconData(IniFile): '''Class to parse and validate IconData Files''' def __init__(self): IniFile.__init__(self) def __repr__(self): return self.getDisplayName() def parse(self, file): IniFile.parse(self, file, [ 'Icon Data']) def getDisplayName(self): return self.get('DisplayName', locale = True) def getEmbeddedTextRectangle(self): return self.get('EmbeddedTextRectangle', list = True) def getAttachPoints(self): return self.get('AttachPoints', type = 'point', list = True) def checkExtras(self): if self.fileExtension != '.icon': self.warnings.append('Unknown File extension') def checkGroup(self, group): if not group == self.defaultGroup and re.match('^\\[X-', group) and group.encode('ascii', 'ignore') == group: self.errors.append('Invalid Group name: %s' % group.encode('ascii', 'replace')) def checkKey(self, key, value, group): if re.match('^DisplayName' + xdg.Locale.regex + '$', key): pass elif key == 'EmbeddedTextRectangle': self.checkValue(key, value, type = 'integer', list = True) elif key == 'AttachPoints': self.checkValue(key, value, type = 'point', list = True) elif re.match('^X-[a-zA-Z0-9-]+', key): pass else: self.errors.append('Invalid key: %s' % key) icondirs = [] for basedir in xdg_data_dirs: icondirs.append(os.path.join(basedir, 'icons')) icondirs.append('/usr/share/pixmaps') icondirs.append(os.path.expanduser('~/.icons')) themes = [] cache = dict() dache = dict() eache = dict() def getIconPath(iconname, size = None, theme = None, extensions = [ 'png', 'svg', 'xpm']): global themes if size == None: size = xdg.Config.icon_size if theme == None: theme = xdg.Config.icon_theme if os.path.isabs(iconname): return iconname if os.path.splitext(iconname)[1][1:] in extensions: iconname = os.path.splitext(iconname)[0] try: if themes[0].name != theme: themes = [] __addTheme(theme) except IndexError: __addTheme(theme) tmp = ''.join([ iconname, str(size), theme, ''.join(extensions)]) if eache.has_key(tmp): if int(time.time() - eache[tmp][0]) >= xdg.Config.cache_time: del eache[tmp] else: return eache[tmp][1] int(time.time() - eache[tmp][0]) >= xdg.Config.cache_time for thme in themes: icon = LookupIcon(iconname, size, thme, extensions) if icon: eache[tmp] = [ time.time(), icon] return icon for directory in icondirs: if (not dache.has_key(directory) or int(time.time() - dache[directory][1]) >= xdg.Config.cache_time or dache[directory][2] < os.path.getmtime(directory)) and os.path.isdir(directory): dache[directory] = [ os.listdir(directory), time.time(), os.path.getmtime(directory)] continue icon for dir, values in dache.items(): for extension in extensions: try: if iconname + '.' + extension in values[0]: icon = os.path.join(dir, iconname + '.' + extension) eache[tmp] = [ time.time(), icon] return icon continue except UnicodeDecodeError: continue if theme != 'hicolor': icon = getIconPath(iconname, size, 'hicolor') eache[tmp] = [ time.time(), icon] return icon def getIconData(path): if os.path.isfile(path): dirname = os.path.dirname(path) basename = os.path.basename(path) if os.path.isfile(os.path.join(dirname, basename + '.icon')): data = IconData() data.parse(os.path.join(dirname, basename + '.icon')) return data def __addTheme(theme): for dir in icondirs: if os.path.isfile(os.path.join(dir, theme, 'index.theme')): __parseTheme(os.path.join(dir, theme, 'index.theme')) break continue if os.path.isfile(os.path.join(dir, theme, 'index.desktop')): __parseTheme(os.path.join(dir, theme, 'index.desktop')) break continue elif debug: raise NoThemeError(theme) def __parseTheme(file): theme = IconTheme() theme.parse(file) themes.append(theme) for subtheme in theme.getInherits(): __addTheme(subtheme) def LookupIcon(iconname, size, theme, extensions): if not cache.has_key(theme.name): cache[theme.name] = [] cache[theme.name].append(time.time() - (xdg.Config.cache_time + 1)) cache[theme.name].append(0) cache[theme.name].append(dict()) if int(time.time() - cache[theme.name][0]) >= xdg.Config.cache_time: cache[theme.name][0] = time.time() for subdir in theme.getDirectories(): for directory in icondirs: dir = os.path.join(directory, theme.name, subdir) if (not cache[theme.name][2].has_key(dir) or cache[theme.name][1] < os.path.getmtime(os.path.join(directory, theme.name))) and subdir != '' and os.path.isdir(dir): cache[theme.name][2][dir] = [ subdir, os.listdir(dir)] cache[theme.name][1] = os.path.getmtime(os.path.join(directory, theme.name)) continue for dir, values in cache[theme.name][2].items(): if DirectoryMatchesSize(values[0], size, theme): for extension in extensions: if iconname + '.' + extension in values[1]: return os.path.join(dir, iconname + '.' + extension) iconname + '.' + extension in values[1] minimal_size = sys.maxint closest_filename = '' for dir, values in cache[theme.name][2].items(): distance = DirectorySizeDistance(values[0], size, theme) if distance < minimal_size: for extension in extensions: if iconname + '.' + extension in values[1]: closest_filename = os.path.join(dir, iconname + '.' + extension) minimal_size = distance continue return closest_filename def DirectoryMatchesSize(subdir, iconsize, theme): Type = theme.getType(subdir) Size = theme.getSize(subdir) Threshold = theme.getThreshold(subdir) MinSize = theme.getMinSize(subdir) MaxSize = theme.getMaxSize(subdir) if Type == 'Fixed': return Size == iconsize if Type == 'Scaleable': if iconsize <= iconsize: return iconsize <= MaxSize iconsize <= iconsize return iconsize if Type == 'Threshold': if iconsize <= iconsize: return iconsize <= Size + Threshold iconsize <= iconsize return iconsize def DirectorySizeDistance(subdir, iconsize, theme): Type = theme.getType(subdir) Size = theme.getSize(subdir) Threshold = theme.getThreshold(subdir) MinSize = theme.getMinSize(subdir) MaxSize = theme.getMaxSize(subdir) if Type == 'Fixed': return abs(Size - iconsize) if Type == 'Scalable': if iconsize < MinSize: return MinSize - iconsize if iconsize > MaxSize: return MaxSize - iconsize return 0 if Type == 'Threshold': if iconsize < Size - Threshold: return MinSize - iconsize if iconsize > Size + Threshold: return iconsize - MaxSize return 0